home *** CD-ROM | disk | FTP | other *** search
- /* WIDE AREA INFORMATION SERVER SOFTWARE
- No guarantees or restrictions. See the readme file for the full standard
- disclaimer.
- 5.29.90 Harry Morris, morris@think.com
- */
-
- /* Copyright (c) CNIDR (see ../COPYRIGHT) */
-
-
- /* this file is a server process for a unix machine that takes input from
- standard in or from a socket and searches the local search engine on the
- unix box.
- originally written by harry morris.
- modified by brewster kahle. 7/90
- 6.xx.90 Brewster - initial implementation of stdio interface
- 7.xx.90 Patrick Bray - support for headers and forking processes
- 90.07.31 Ephraim - support for logging
-
- 91.03.03 Jonathan - set searchLog to log_out.
- 91.05.23 Jonathan - added fork process for indexer.
- Fixed version display so it exits.
- 91.05.25 Jonathan - added setuid.
-
- Tue Jul 9 12:11:02 1991 -- Michael Haberler mah@wu-wien.ac.at
-
- Added semi-intelligent INFO database indexing (only done if
- any of the .src files is newer than INFO.dct)
-
- Locking against multiple concurrent INFO rebuilds if
- running under inetd
-
- Use scandir() for directory operations
-
- Works under inetd as well as standalone. Here are my inetd.conf
- entries (not the missing userid in the Ultrix inetd.conf!):
-
- hpux 7.0/800, Interactive/386 2.2.1:
- z3950 stream tcp nowait root /usr/local/etc/waisserver waisserver -s \
- -d /usr/logins/mah/wais-sources
-
- Ultrix 4.1:
- z3950 stream tcp nowait /usr/local/etc/waisserver waisserver -s \
- -d /usr/logins/mah/wais-sources
-
- Also, add the next line to /etc/services, and tickle your YP server:
- z3950 210/tcp # wide area information server (wais)
-
- * $Log: waissrch.c,v $
- * Revision 1.1 1994/03/29 14:11:07 shangjiej
- * Initial revision
- *
- * Revision 1.3 93/07/21 18:52:39 warnock
- * Renamed from server.c.
- * Added STELAR-specific patches
- *
- * Revision 1.2 93/07/01 19:19:53 warnock
- * gethostname -> mygethostname
- *
- * Revision 1.1 1993/02/16 15:05:35 freewais
- * Initial revision
- *
- * Revision 1.48 92/05/10 14:47:39 jonathan
- * Update for release.
- *
- * Revision 1.47 92/05/06 17:34:01 jonathan
- * Changed auto-indexing of .src files to use filename_finish_header_function.
- *
- * Revision 1.46 92/05/04 17:18:32 jonathan
- * Fixed use of merge_pathname in creating INFO database.
- *
- * Revision 1.45 92/04/28 15:19:18 jonathan
- * Added decoding of IP address to DNS name in init message handler.
- *
- * Revision 1.44 92/03/26 18:26:41 jonathan
- * Added extra arguments to index_text_file call.
- *
- * Revision 1.43 92/03/07 19:41:47 jonathan
- * Added IBM defines, courtesy mycroft@hal.gnu.ai.mit.edu,
- *
- * Revision 1.42 92/03/05 07:07:58 shen
- * add two more dummy arguments to call to init_search_engine
- *
- * Revision 1.41 92/02/27 09:58:50 jonathan
- * Put back in setting of core limit to max value, when SET_LIMIT is defined.
- *
- * Revision 1.40 92/02/24 10:07:41 jonathan
- * Removed reporting functions.
- *
- * Revision 1.39 92/02/21 12:27:15 jonathan
- * Changed logging of segmentation violation and bus errors to mark log with
- * an error code, and close code.
- *
- * Revision 1.38 92/02/21 11:00:45 jonathan
- * Added wais_log_level
- *
- * Revision 1.37 92/02/19 10:16:25 jonathan
- * Added build_catalog to auto-indexer.
- *
- * Revision 1.36 92/02/16 12:33:21 jonathan
- * Removed code refering to NOINETNTOA, since we should use inet_ntoa.
- *
- * Revision 1.35 92/02/16 12:05:18 jonathan
- * Added code for GCC incompatibility in inet_ntoa (passing structure as
- * pointer).
- *
- * Revision 1.34 92/02/14 09:07:34 jonathan
- * Set MAXNAPTIME to 0 so it won't sleep. Changed the WLOG_ERROR to
- * WLOG_WARNING in the log entry.
- *
- * Revision 1.33 92/02/12 13:44:20 jonathan
- * Added "$Log" so RCS will put the log message in the header
- *
- *
- */
-
- #define SERVER_DATE "Fri April 9 1993"
-
- #ifndef lint
- static char *RCSid = "$Header: /archives/stelar/src/freeWAIS/freeWAIS-0.2/ir/RCS/waisserver.c,v 1.3 93/07/21 18:52:39 warnock Exp $";
- #endif
-
- #define INFO_DICT "INFO.dct"
- #ifdef WIN32
- /* char LOCKFILE[MAX_PATH+1]; move further down as MAX_PATH undefined here */
- #define NAPTIME 1000 /* milliseconds */
- #else
- #define LOCKFILE "/tmp/INFO.lock" /* while re-indexing INFO */
- #define NAPTIME 1 /* seconds */
- #endif
- #define MAXNAPTIME 0 /* Don't wait, just go on. */
-
- #include "server.h"
- #include "sockets.h"
- #include <sys/types.h>
- #include <sys/stat.h>
- #ifdef ULTRIX
- /* #include <sys/file.h> */
- #include <fcntl.h>
- #else
- #ifdef _IBMR2
- #include <fcntl.h>
- #else /* ! _IBMR2 */
- #ifdef USG
- #include <sys/fcntl.h>
- #else
- #ifdef WIN32
- #include <fcntl.h>
- #include <io.h>
- #else
- #include <sys/file.h>
- #endif /* WIN32 */
- #endif
- #endif /* _IBMR2 */
- #endif /* else ultrix */
- #ifdef SYSV
- #define SIGCHLD SIGCLD
- #endif
-
- #ifdef sgi
- #include <sys/signal.h>
- #else
- #include <signal.h>
- #endif
-
- #include <string.h>
- #include "irdirent.h"
- #include "panic.h"
- #include "ustubs.h"
- #include "transprt.h"
- #include "wmessage.h"
- #include "ir.h"
- #include "wprot.h"
- #include "cutil.h"
- #include "futil.h"
- #include "irext.h"
- #include "irsearch.h"
-
- /* to create the INFO index */
- #include "irtfiles.h"
- #include "irfiles.h"
- #include "irhash.h"
- #include "version.h"
-
- #ifdef WIN32
- char LOCKFILE[MAX_PATH+1];
- void stop_list_file(char *filename);
- boolean server_security(char *index_directory, char *database_name);
- #endif
- #ifdef DEBUG
- FILE *debug_log;
- #endif
-
- static long bufferSize = BUFSZ; /* how much we are using
- (we get one of these per process) */
-
-
- extern char host_name[255], host_address[255];
-
- /* Bitmap association table -- LEB/HSTX 8/5/92 */
- #ifdef STELAR
- #define LOOKUP_TABLE /archives/stelar/abs/wais/bitmap.table
-
- char *bitmap_table = "LOOKUP_TABLE";
-
- /* char *bitmap_table = "/archives/stelar/abs/wais/bitmap.table"; */
- #endif /* STELAR */
-
- /*---------------------------------------------------------------------------*/
- #ifdef WIN32
- #define TIMEOUT_LENGTH 3600000 /* one hour timeout. */
- #else
- #define TIMEOUT_LENGTH 3600 /* one hour timeout. */
- #endif
- #define IDLE_TIME "1 hour"
-
- void
- serve_client(in,out, index_directory)
- FILE* in;
- FILE* out;
- char *index_directory;
- {
- char buf[BUFSZ]; /* contains the message and header */
- char *bufPtr ; /* points at the begining of the z3950 */
- long size; /* bytes in the z3950 message */
- WAISMessage header; /* for storing the header */
- long i;
- long bytesLeft;
- long nextChar;
- #ifndef WIN32
- struct itimerval new, old;
-
- new.it_interval.tv_sec = 0;
- new.it_interval.tv_usec = 0;
- new.it_value.tv_sec = TIMEOUT_LENGTH;
- new.it_value.tv_usec = 0;
-
- getitimer(ITIMER_REAL, &old);
- while (TRUE)
- {
- /* try to read the header */
- for (i = 0; i < HEADER_LENGTH; i++)
- {
- setitimer(ITIMER_REAL, &new, NULL);
- nextChar = fgetc(in);
- if (nextChar == EOF) /* my connection exited, so will I */
- {
- return;
- }
- else
- buf[i] = (char)nextChar;
- }
-
- setitimer(ITIMER_REAL, &old, NULL);
- #else
- UINT timerid;
- while (TRUE)
- {
- /* try to read the header */
- timerid = SetTimer(NULL, 0, TIMEOUT_LENGTH, NULL);
- for (i = 0; i < HEADER_LENGTH; i++)
- {
- nextChar = fgetc(in);
- if (nextChar == EOF) /* my connection exited, so will I */
- {
- KillTimer(NULL, timerid);
- return;
- } else
- buf[i] = (char)nextChar;
- }
- KillTimer(NULL, timerid);
- #endif /* WIN32 */
-
- /* parse the header */
- readWAISPacketHeader(buf,&header);
-
- /* make sure we have the right version.
- If we dont, we dont know what to do. */
- if (header.hdr_vers > HEADER_VERSION)
- panic("Incompatable header versions (Current version: %c, supplied version: %c.",
- HEADER_VERSION, header.hdr_vers) ;
-
- /* determine the size of the z3950 message */
- {
- char length_array[11];
- strncpy(length_array, header.msg_len, 10);
- length_array[10] = '\0';
- size = atol(length_array);
- }
-
- /* set bufPtr to start the z3950 message */
- bufPtr = buf + HEADER_LENGTH ;
-
- /* read the z3950 message */
- #ifdef WIN32
- timerid = SetTimer(NULL, 0, TIMEOUT_LENGTH, NULL);
- for (i = 0; i < size ; i++) {
- buf[i + HEADER_LENGTH] = (char)fgetc(in) ;
- }
- KillTimer(NULL, timerid);
- #else
- for (i = 0; i < size ; i++) {
- setitimer(ITIMER_REAL, &new, NULL);
- buf[i + HEADER_LENGTH] = (char)fgetc(in) ;
- }
- #endif
-
- rewind(in);
-
- /* decode the z3950 if necessary */
- transportDecode((long)header.encoding,bufPtr,&size);
-
- /* XXX handle compression options */
-
- /* process it the z3950 */
- bytesLeft = bufferSize;
-
- size = interpret_buffer(bufPtr,size,bufPtr,bytesLeft,
- &bufferSize,(long)header.hdr_vers,
- index_directory);
-
- /* re-encode the message if necessary */
- transportCode((long)header.encoding,bufPtr,&size);
-
- /* XXX handle compression options */
-
- /* write the new header */
- writeWAISPacketHeader(buf,size,
- (long)header.msg_type,header.server,
- (long)header.compression,(long)header.encoding,
- (long)header.hdr_vers);
-
- /* write the whole response to the output file */
- for (i = 0; i < size + HEADER_LENGTH; i++)
- fputc(buf[i],out) ;
-
- fflush(out); /* flush any file buffers */
- rewind(out); /* reset the file for read */
-
- }
- }
-
- /*---------------------------------------------------------------------------*/
-
- #ifndef ISC
- #ifndef LINUX
- static void breakKey _AP((long s1,long s2,struct sigcontext* s3,char* s4));
- #endif
- #endif
-
- static void
- breakKey (s1,s2,s3,s4)
- long s1;
- long s2;
- struct sigcontext *s3;
- char *s4;
- {
- if(0 != finished_search_engine())
- panic("unable to close search engine");
- panic ("got a ^c");
- signal (SIGINT, (void *)breakKey);
- }
-
- /*---------------------------------------------------------------------------*/
-
- void
- childhandler(sig, code, scp, addr)
- long sig, code;
- struct sigcontext *scp;
- char *addr;
- {
- #ifndef WIN32
- wait(NULL); /* give the kid a decent burial */
- signal (SIGCHLD, childhandler); /* Dave Judd - IRIX requires resetting signal */
- #endif
- }
-
- /*---------------------------------------------------------------------------*/
-
- void
- alarmhandler(sig, code, scp, addr)
- long sig, code;
- struct sigcontext *scp;
- char *addr;
- {
- waislog(WLOG_HIGH, WLOG_CLOSE,
- "Server idle longer %s. Closing server and exiting.", IDLE_TIME);
- if(0 != finished_search_engine())
- panic("unable to close search engine");
- exit(0);
- }
-
- /*---------------------------------------------------------------------------*/
-
- void
- seghandler(sig, code, scp, addr)
- long sig, code;
- struct sigcontext *scp;
- char *addr;
- {
- waislog(WLOG_HIGH, WLOG_ERROR, "Segmentation violation.");
- waislog(WLOG_HIGH, WLOG_CLOSE, "Bummer. Closing server and exiting.");
- #ifdef DUMPCORE
- abort();
- #else
- exit(-1);
- #endif
- }
-
- /*---------------------------------------------------------------------------*/
-
- void
- bushandler(sig, code, scp, addr)
- long sig, code;
- struct sigcontext *scp;
- char *addr;
- {
- waislog(WLOG_HIGH, WLOG_ERROR, "Bus error.");
- waislog(WLOG_HIGH, WLOG_CLOSE, "Bummer. Closing server and exiting.");
- #ifdef DUMPCORE
- abort();
- #else
- exit(-1);
- #endif
- }
-
- /*---------------------------------------------------------------------------*/
-
- #ifndef WIN32
- #include <pwd.h>
-
- int finduid(name)
- char *name;
- {
- struct passwd *pwent;
-
- if ((pwent = getpwnam(name)) == NULL) {
- return -1;
- }
-
- return(pwent->pw_uid);
- }
- #endif
-
- static char *index_dir = NULL;
- static time_t info_change_time;
- static int indexing_needed = 0;
- static char *info_dict = INFO_DICT;
-
- extern int alphasort();
-
- /* selecttion function for scandir()
- * trigger on ".src" extension, regular file, and != "INFO.src"
- * Indexing is needed if any of the .src files is younger than
- * INFO.dct
- */
- static int
- srcfiles(e)
- struct dirent *e;
- {
- #ifndef WIN32
- struct stat sb;
- char *lastdot = strrchr(e->d_name,'.');
- int candidate;
-
- candidate = lastdot &&
- (stat(merge_pathnames(e->d_name,index_dir), &sb) >= 0) &&
- ((sb.st_mode & S_IFMT) == S_IFREG) &&
- !strcmp(lastdot,source_ext) &&
- strcmp(e->d_name,info_dict); /* whew */
-
- if (candidate) {
- indexing_needed |= (sb.st_mtime > info_change_time);
- return 1;
- }
- #endif
- return 0;
- }
-
-
- /*---------------------------------------------------------------------------*/
-
- #ifdef SET_LIMIT
- #include <sys/resource.h>
- #endif
-
- #ifndef WIN32
- #define INDEX_FORK
-
- extern char *inet_ntoa ();
- #endif
- extern char *syslog_name;
-
- void
- main(argc,argv)
- int argc;
- char* argv[];
- {
- #ifndef WIN32
- FILE *file;
- #endif
- #ifdef DEBUG
- int i;
- #endif
- char *next_argument = next_arg(&argc, &argv), *command_name;
- boolean use_stdio = TRUE; /* default is true */
- /* char *log_file_name = NULL; */ /* name of file for error output */
- char *uid_name = "root"; /* user id so setuid if root */
- int uid = 0; /* if not specified, leave as root. */
- #ifndef WIN32
- long socket;
- int child_proc; /* for the child process id */
- int child;
- #endif
- long cm_mem_percent = 0; /* default */
- struct stat statbuf;
- #ifndef WIN32
- struct dirent **list;
- #endif
- int naptime = 0;
- extern int errno;
- extern char *sys_errlist[];
- extern void filename_finish_header_function();
- dataopsrec dataops;
-
- #ifdef SET_LIMIT
- struct rlimit rlp;
-
- getrlimit(RLIMIT_CORE, &rlp);
- rlp.rlim_cur = rlp.rlim_max;
- setrlimit(RLIMIT_CORE, &rlp);
- getrlimit(RLIMIT_DATA, &rlp);
- rlp.rlim_cur = rlp.rlim_max;
- setrlimit(RLIMIT_DATA, &rlp);
- #endif
-
- #ifdef WIN32
- /* Turn stdout buffering off */
- setvbuf(stdout,NULL,_IONBF,0);
- /* We need binary mode for standard input and output -- no translation CR-LF*/
- _setmode(_fileno(stdin), _O_BINARY);
- _setmode(_fileno(stdout), _O_BINARY);
- #endif /*WIN32 */
-
- /* dgg -- must duplicate mods to waisindex.c, here is mini-build of INFO.src */
- dataops.separator_function= NULL;
- dataops.header_function= NULL;
- dataops.date_function= NULL;
- dataops.finish_header_function= filename_finish_header_function;
- dataops.type= "WSRC";
- dataops.wordDelimiter= wordbreak_notalnum;
- dataops.addseparatorwords= false;
- dataops.extraheaderweight= true;
- dataops.repeat_weight= 1;
- dataops.minwordlen= 2;
- stop_list_file("\0");
- gDelimiters[0]= '\0';
- wordDelimiter= wordbreak_notalnum;
- /* dgg -- end new inits */
-
- #ifdef DEBUG
- /*DebugBreak();/**/
- debug_log = fopen("waisserv.log", "a");
- fprintf(debug_log, "WAISSERV has been called with following arguments argc = %d:\n", argc);
- for (i = 0; i < argc; i++)
- fprintf(debug_log, "argv[%d] = %s\n", i, argv[i]);
- #endif
- tcp_port = 210; /* tcp_port to use */
- command_name = next_argument;
- #ifdef WIN32
- syslog_name = (syslog_name = (char *)strrchr(command_name, '\\')) ? (syslog_name + 1) : command_name;
- #else
- syslog_name = (syslog_name = (char *)rindex(command_name, '/')) ? (syslog_name + 1) : command_name;
- #endif
- host_name[0] = 0;
- host_address[0] = 0;
-
- server_name = s_malloc(255);
- mygethostname(server_name, 255);
-
- #ifdef WIN32
- wais_pid = 0;
- #else
- wais_pid = getpid();
- #endif
-
- #ifdef DEBUG
- fprintf(debug_log, "command_name = %s\n", command_name);
- #endif
-
- if (!strcmp(command_name, "waisserver.d")) {
- struct sockaddr_in source;
- int sourcelen;
-
- sourcelen = sizeof(struct sockaddr_in);
-
- #ifdef WIN32
- if (!getpeername(fileno(stdout),(struct sockaddr *)&source,&sourcelen)) {
- #else
- if (!getpeername(fileno(stdout),
- (void *)&source,&sourcelen)) {
- #endif
- struct hostent *peer = NULL;
-
- #ifdef WIN32
- peer = gethostbyaddr((char *)&source.sin_addr.s_addr, 4, PF_INET); /* is it right? */
- #else
- #ifdef __DGUX__
- peer = gethostbyaddr((char *)&source.sin_addr.s_addr, 4, AF_INET);
- #else
- peer = gethostbyaddr((void *)&source.sin_addr, 4, AF_INET);
- #endif
- #endif
- if(peer != NULL) {
- sprintf(host_name, "%s", peer->h_name);
-
- sprintf(host_address, "%s",
- #if defined(sparc) && defined(__GNUC__)
- inet_ntoa(&source.sin_addr)
- #else
- inet_ntoa(source.sin_addr)
- #endif /* sparc */
- );
- }
- }
- else sprintf(host_address, "Error getting socket: %d, %s.", errno, sys_errlist[errno]);
-
- use_stdio = TRUE;
- }
-
- if (argc == 0){
- #ifdef DEBUG
- fprintf(debug_log, "argc = 0\n");
- #endif
-
- #ifdef WIN32
- fprintf(stderr,"Usage: %s [-s] [-d directory] [-v] [-e file] [-l level]\n",command_name);
- #else
- fprintf(stderr,"Usage: %s [-p [port_number]] [-s] [-d directory] [-u user] [-cmmem number] [-v]\n",
- command_name);
- fprintf(stderr," -p [port] listen to the port. If the port is supplied, then\n");
- fprintf(stderr," that tcp_port number is used. If it is not supplied \n");
- fprintf(stderr," then the Z39.50 port (210) is used.\n");
- #endif
- fprintf(stderr," -d directory: means to use the directory as the source of databases.\n");
- fprintf(stderr," Defaults to the current directory.\n");
- #ifdef WIN32
- fprintf(stderr," -e [file]: set log output to file, or NUL: if not specified.\n");
- #else
- fprintf(stderr," -e [file]: set log output to file, or /dev/null if not specified.\n");
- #endif
- fprintf(stderr," -l log_level: set log level. 0 means log nothing,\n");
- fprintf(stderr," 10 [the default] means log everything.\n");
- fprintf(stderr," -s means listen to standard I/O for queries. This is the default\n");
- #ifndef WIN32
- fprintf(stderr," -u user: if started as root, setuid to user after startup.\n");
- fprintf(stderr," -cmmem number: percentage of CM memory to use (CM code only).\n");
- #endif
- fprintf(stderr," -v prints the version.\n");
- exit(1);
- }
- if(NULL == (next_argument = next_arg(&argc, &argv))){
- fprintf(stderr,"No arguments specified\n");
- exit(0);
- }
- while((next_argument != NULL) &&
- ('-' == next_argument[0])){
-
- /* then we have an argument to process */
- if (0 == strcmp("-p", next_argument)){
- char *peek_argument = peek_arg(&argc, &argv);
- use_stdio = FALSE;
- if ((NULL != peek_argument) && /* if we are not out of args */
- ('-' != peek_argument[0])){ { /* and the next isn't an option... */
- /* get the port number */
- tcp_port = atoi(next_arg(&argc, &argv));
- } /* end if (explicit tcp_port) */
- }
- } /* end if (-p) */
- else if (0 == strcmp("-s", next_argument)){
- use_stdio = TRUE;
- } /* end if (-s) */
-
- else if (0 == strcmp("-e", next_argument)) {
- char *peek_argument = peek_arg(&argc, &argv);
- #ifdef WIN32
- log_file_name = "NUL:"; /* default to NUL: */
- #else
- log_file_name = "/dev/null"; /* default to /dev/null */
- #endif
- if ((peek_argument != NULL) &&
- ('-' != peek_argument[0])) {
- log_file_name = next_arg(&argc, &argv);
- } /* end if (explicit log file) */
- } /* end if (-e) */
- else if (0 == strcmp("-l", next_argument)) {
- wais_log_level = atol(next_arg(&argc, &argv));
- } /* end if (-l) */
- else if (0 == strcmp("-d", next_argument)) {
- index_dir = next_arg(&argc, &argv);
- }
- else if (0 == strcmp("-v", next_argument)) {
- fprintf(stderr,"%s: %s, %s\n", command_name, VERSION, SERVER_DATE);
- #ifdef WIN32
- fprintf(stderr,"%s\n",VERWIN32);
- if (argc == 2)
- exit(0);
- #endif
- }
- #ifndef WIN32
- else if (0 == strcmp("-u", next_argument)) {
- uid_name = next_arg(&argc, &argv);
- if((uid = finduid(uid_name)) < 0)
- panic("Couldn't find user %s.", uid_name);
- }
- else if(0 == strcmp("-cmmem", next_argument)){
- if(NULL == (next_argument = next_arg(&argc, &argv)))
- panic("Expected a number (1-100) for percentage of memory to use");
- cm_mem_percent = atol(next_argument);
- if(cm_mem_percent < 1)
- panic("The -cmmem argument should not be less than 1 and less than 100");
- if(cm_mem_percent > 100)
- panic("Warning: The -cmmem parameter was %ld%%. It should be between 1-100.", cm_mem_percent);
- }
- #endif
- else{
- panic("Don't recognize the %s option", next_argument);
- }
- next_argument = next_arg(&argc, &argv);
- } /* end while (more arguments) */
-
- if (use_stdio && log_file_name == NULL)
- #ifdef WIN32
- log_file_name = "NUL:";
- #else
- log_file_name = "/dev/null";
- #endif
- if (log_file_name == NULL)
- logfile = stderr;
- else logfile = NULL;
-
- index_dir = index_dir ? index_dir : ".";
- info_dict = s_strdup(merge_pathnames(info_dict,index_dir));
-
- if(0 != init_search_engine(index_dir, false, true, cm_mem_percent,0,0))
- panic("unable to initialize search engine");
-
- /* remember timestamp on INFO.dct if rebuilding needed
- * If it doesnt exist, it's assumed to be *very* old, to force
- * re-indexing
- */
- info_change_time = (stat(info_dict,&statbuf) == -1) ? 0 : statbuf.st_mtime;
- #ifdef WIN32
- /* this will replace from scandir to freedir */
- #ifdef NOT_NOW
- /* We are not yet supporting dynamically indexing.
- * It could be done by WAISINDEX tool manually.
- */
- if (info_change_time == 0) indexing_needed = TRUE;
- if (FALSE) {
-
- /* Time to re-index,
- * aquire the lock
- */
- waislog(WLOG_MEDIUM, WLOG_INDEX,
- "re-indexing needed, info_change_time=%d",info_change_time);
-
- if (GetTempPath(sizeof(LOCKFILE), LOCKFILE) == 0) {
- panic("Warning - couldn't get the system temporary path %s", LOCKFILE);
- }
- LOCKFILE[MAX_PATH] = 0;
- strcat(LOCKFILE, "\\INFO.LCK");
- LOCKFILE[MAX_PATH] = 0;
- if (open(LOCKFILE, _O_WRONLY|_O_CREAT|_O_EXCL,0666) == -1) {
-
- /* already locked by somebody else
- * spin till she finishes
- */
- while (!(stat(LOCKFILE,&statbuf) == -1)) {
- Sleep(NAPTIME); /* NAPTIME is 1000 millisecs, ie, 1 sec */
- naptime ++; /* in seconds */
- waislog(WLOG_MEDIUM, WLOG_INFO,
- "INFO locked, waiting since %d seconds", naptime);
- if (naptime > MAXNAPTIME) {
- waislog(WLOG_HIGH, WLOG_WARNING,
- "Warning - lockfile %s won't go away after %d seconds, not reindexing.",
- LOCKFILE, naptime);
- break;
- }
- }
- /* if lockfile went away, assume INFO.* build finished
- * so just use it
- */
- } else { /* we aquired the lock, so rebuild database */
- HANDLE hSearch;
- WIN32_FIND_DATA FindData;
- char Name[MAX_PATH+1];
-
- strncpy(Name,index_dir,MAX_PATH);
- Name[MAX_PATH] = '\0';
- strncat(Name,"\\*.*",MAX_PATH);
- Name[MAX_PATH] = '\0';
- hSearch = FindFirstFile(Name,&FindData);
- if (hSearch!=INVALID_HANDLE_VALUE) {
- struct stat st;
- char *lastdot;
- int candidate;
- database *db;
- char *dbname;
-
- dbname = s_strdup(merge_pathnames("INFO", index_dir));
- db = openDatabase(dbname, true, /* maybe this should append XXX */
- false);
- s_free(dbname);
- init_add_word(db, 0, 100000L);
-
- strncpy(Name, index_dir, MAX_PATH);
- Name[MAX_PATH] = '\0';
- if (index_dir[strlen(index_dir)-1] != '\\')
- strncat(Name, "\\", MAX_PATH);
- dbname = strrchr(Name, '\\');
- Name[MAX_PATH] = '\0';
- if (!dbname)
- panic("No path separator \\");
-
- while (TRUE) {
- lastdot = strrchr(FindData.cFileName, '.');
- candidate = lastdot &&
- (stat(merge_pathnames(FindData.cFileName,index_dir), &st) >= 0) &&
- ((st.st_mode & S_IFMT) == S_IFREG) &&
- !strcmp(lastdot,source_ext) &&
- strcmp(FindData.cFileName,info_dict); /* whew */
-
- if ((candidate) && (st.st_mtime > info_change_time)) {
- /* do need indexing */
- strncat(dbname, FindData.cFileName, MAX_PATH);
- waislog(WLOG_MEDIUM, WLOG_INDEX, "Indexing %s",dbname);
- index_text_file(dbname, &dataops, db, true, false, false, true);
- }
-
- if (!FindNextFile(hSearch,&FindData)) break;
- }
- FindClose(hSearch);
- if(!probe_file(source_filename(Name, db)))
- write_src_structure(source_filename(Name, db),
- "INFO", "WSRC", NULL, 0L, true, tcp_port);
- finished_add_word(db);
- build_catalog(db);
- closeDatabase(db);
- if (unlink(LOCKFILE))
- panic("Indexer: cant unlink lockfile!\n");
- waislog(WLOG_MEDIUM, WLOG_INDEX, "Indexer done");
- }
- }
- }
- #endif /* if NOT_NOW */
-
- #else /* WIN32 */
- /* compare with candidates */
-
- if (scandir(index_dir, &list, srcfiles, alphasort) < 0) {
- waislog(WLOG_HIGH, WLOG_ERROR,
- "Error: reading directory %s, %s",
- index_dir, sys_errlist[errno]);
- indexing_needed = FALSE;
- }
-
- /* ok. we know if we need indexing,
- * and have all the filenames.
- */
-
- if (info_change_time == 0) indexing_needed = TRUE;
- if (indexing_needed) {
-
- /* Time to re-index,
- * aquire the lock
- */
- waislog(WLOG_MEDIUM, WLOG_INDEX,
- "re-indexing needed, info_change_time=%d",info_change_time);
-
- if (open(LOCKFILE, O_WRONLY|O_CREAT|O_EXCL,0666) == -1) {
-
- /* already locked by somebody else
- * spin till she finishes
- */
- while (!(stat(LOCKFILE,&statbuf) == -1)) {
- sleep(NAPTIME);
- naptime += NAPTIME;
- waislog(WLOG_MEDIUM, WLOG_INFO,
- "INFO locked, waiting since %d seconds", naptime);
- if (naptime > MAXNAPTIME) {
-
- waislog(WLOG_HIGH, WLOG_WARNING,
- "Warning - lockfile %s won't go away after %d seconds, not reindexing.",
- LOCKFILE, naptime);
- break;
- }
- }
- /* if lockfile went away, assume INFO.* build finished
- * so just use it
- */
- } else { /* we aquired the lock, so rebuild database */
-
- #ifdef INDEX_FORK
- if (!(child = fork())) {
- #endif
- database *db;
- struct dirent **s = list;
- char filename[MAX_FILENAME_LEN], *dbname;
-
- waislog(WLOG_MEDIUM, WLOG_INDEX,
- "Creating INFO database, pid=%d",getpid());
- dbname = s_strdup(merge_pathnames("INFO", index_dir));
- db = openDatabase(dbname, true, /* maybe this should append XXX */
- false);
- s_free(dbname);
- init_add_word(db, 0, 100000L);
-
- while (*s) { /* index it */
- strncpy(filename, index_dir, MAX_FILENAME_LEN);
- if(index_dir[strlen(index_dir) -1] != '/')
- strncat(filename, "/", MAX_FILENAME_LEN);
- strncat(filename, (*s)->d_name, MAX_FILENAME_LEN);
- waislog(WLOG_MEDIUM, WLOG_INDEX,
- "Indexing %s", filename);
- index_text_file(filename, &dataops, db, true, false,
- false, true, NULL, NULL);
- s++;
- }
- freedir(list); /* array of filenames */
-
- if(!probe_file(source_filename(filename, db)))
- write_src_structure(source_filename(filename, db),
- "INFO", "WSRC", NULL, 0L, true, tcp_port);
- finished_add_word(db);
- build_catalog(db);
- closeDatabase(db);
- if (unlink(LOCKFILE))
- panic("Indexer: cant unlink lockfile!\n");
- waislog(WLOG_MEDIUM, WLOG_INDEX,
- "Indexer pid=%d done", getpid());
-
- #ifdef INDEX_FORK
- exit(0); /* indexing child */
- }
- else if (child == -1) {
- waislog(WLOG_HIGH, WLOG_ERROR,
- "Unable to fork for indexer.");
- exit(1);
- }
- /* wait for child process */
- else while (wait(0) != child) ; /* do nothing */
- #endif
-
- }
- }
- #endif /* WIN32 */
-
-
- if (use_stdio == TRUE) {
- if(host_address[0] != 0){
- waislog(WLOG_MEDIUM, WLOG_CONNECT,
- "Accepted connection from: %s [%s], %s",
- host_name, host_address, VERSION);
- }
- else{
- waislog(WLOG_MEDIUM, WLOG_CONNECT,
- "Couldn't determine peer connection. %s", VERSION);
- }
-
- if ( server_security(index_dir,NULL) != true ){
- waislog(WLOG_HIGH, WLOG_INFO,"Closing down server");
- exit(-1);
- }
-
- }
- else{
- waislog(WLOG_MEDIUM, WLOG_INFO, "Running server %s", VERSION);
- }
-
- #ifndef WIN32
- signal(SIGINT, (void *)breakKey);
-
- signal(SIGCHLD, childhandler); /* XXX dont really need this any more */
- signal(SIGALRM, alarmhandler);
-
- signal(SIGSEGV, seghandler);
-
- signal(SIGBUS, bushandler);
-
-
- if(use_stdio == FALSE)
- {
- if (tcp_port < 1024 && getuid() != 0) {
- waislog(WLOG_HIGH, WLOG_ERROR,
- "Error opening port %d: Must be superuser to use a port < 1024",
- tcp_port);
- exit(-1);
- }
-
- open_server(tcp_port,&socket,BUFSZ);
-
- #ifdef SECURE_SERVER
- /* if root, setuid to user specified id. */
- if (uid > 0 && getuid() == 0) {
- waislog(WLOG_MEDIUM, WLOG_INFO,
- "Setting uid to %s.", uid_name);
- if (log_file_name && *log_file_name &&
- chown(log_file_name,uid,getgid()) < 0)
- waislog(WLOG_HIGH, WLOG_ERROR,
- "Unable to chown log file to %s!", uid_name);
- if ( 0 > setuid(uid)) {
- waislog(WLOG_HIGH, WLOG_ERROR,
- "Unable to setuid to %s! Exiting.", uid_name);
- exit(-1);
- }
- }
- #endif
- while (TRUE) { /* be a server for several connections */
- accept_client_connection(socket,&file);
-
- if ((child_proc = fork()) == 0) {
-
- /* grandson handles this connection
- * double-fork takes care of zombies
- */
- if ((child_proc = fork()) == 0) {
- wais_pid = getpid();
- log_line = 0;
- serve_client(file, file, index_dir);
- /* but leaves server up */
- close_client_connection(file);
- close_server(socket);
- /* just exits this child */
- waislog(WLOG_MEDIUM, WLOG_CLOSE,
- "Done handling client");
- exit(0);
- } else {
- /* son: orphans the grandchild, so init picks up
- * the exit status
- */
- exit(0);
- }
- } else {
- waislog(WLOG_MEDIUM, WLOG_INFO,
- "Child PID = %d", child_proc);
- close_client_connection(file); /* parent shouldn't keep the file */
- }
- }
- }
- else if(use_stdio == TRUE)
- #else
- if(use_stdio == TRUE)
- #endif /* !WIN32 */
- { /* connections on stdio don't use child processes yet */
- serve_client(stdin, stdout, index_dir);
- waislog(WLOG_MEDIUM, WLOG_CLOSE,
- "Done handling client");
- /* close the whole thing */
- if(0 != finished_search_engine())
- panic("unable to close search engine");
- exit(0);
- }
- }
-
- /*---------------------------------------------------------------------------*/
-
-